var FontMelement = function (dom, fontSize, fontSizeUnit) {
    this.dom = dom;
    this.fontSize = fontSize;

    this.fontSizeUnit = fontSizeUnit || "px";
};

FontMelement.prototype.update = function (ph, origin, size) {
    if (this.fontSize != null) {
        this.dom.style.fontSize = this.fontSize * ph + this.fontSizeUnit;
    }
};

var CMelement = function (dom, x, y, width, height, xUnit, yUnit, widthUnit, heightUnit) {
    this.dom = dom;
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;

    this.xUnit = xUnit || "px";
    this.yUnit = yUnit || "px";
    this.widthUnit = widthUnit || "px";
    this.heightUnit = heightUnit || "px";
    this.dom.melement = this;
};
CMelement.prototype.update = function (ph, origin, size) {
    if (this.x != null) {
        var width = this.width || this.dom.clientWidth;
        this.dom.style.left = (this.x - width / 2) * ph + origin.x + this.xUnit;
    }
    if (this.y != null) {
        var height = this.height || this.dom.clientHeight;
        this.dom.style.top = (this.y - height / 2) * ph + origin.y + this.yUnit;
    }
    if (this.width != null) {
        this.dom.style.width = this.width * ph + this.widthUnit;
    }
    if (this.height != null) {
        this.dom.style.height = this.height * ph + this.heightUnit;
    }
};
var Melement = function (dom, left, top, width, height, leftUnit, topUnit, widthUnit, heightUnit) {
    this.dom = dom;
    this.left = left;
    this.top = top;
    this.width = width;
    this.height = height;

    this.leftUnit = leftUnit || "px";
    this.topUnit = topUnit || "px";
    this.widthUnit = widthUnit || "px";
    this.heightUnit = heightUnit || "px";
};

Melement.prototype.update = function (ph) {
    if (this.left != null) {
        this.dom.style.left = this.left * ph + this.leftUnit;
    }
    if (this.top != null) {
        this.dom.style.top = this.top * ph + this.topUnit;
    }
    if (this.width != null) {
        this.dom.style.width = this.width * ph + this.widthUnit;
    }
    if (this.height != null) {
        this.dom.style.height = this.height * ph + this.heightUnit;
    }
};

var ArtWord = function (picSrc, twidget, splash, digit, cellW, cellH) {
    this.mes = [];
    Object.assign(this, {
        picSrc, twidget, splash, digit, cellW, cellH
    });
    this.dom = document.createElement("div");
    Object.assign(this.dom.style, {
        pointerEvents: "none",
        position: "absolute",
    });
    this.splash.appendChild(this.dom);
    this.initMe();
};
ArtWord.BG_TABLE = {
    "%": "-10%",
    1: "0%",
    2: "10%",
    3: "20%",
    4: "30%",
    5: "40%",
    6: "50%",
    7: "60%",
    8: "70%",
    9: "80%",
    0: "90%",
};
ArtWord.prototype.initMe = function () {
    var w = this.digit * this.cellW;
    var w2 = w / 2;
    var pos = 0;
    for (var i = 0; i < this.digit + 1; i++) {
        var word = document.createElement("div");
        Object.assign(word.style, {
            pointerEvents: "none",
            background: "url(" + this.picSrc + " )",
            backgroundSize: "cover",
            backgroundPosition: "0%",
            position: "absolute",
        });

        this.dom.appendChild(word);
        var me = this.twidget.addMe(new CMelement(word, -w2 + (pos * this.cellW) + this.cellW / 2, 0, this.cellW, this.cellH));
        this.mes.push(me);
        pos++;
    }
    this.mes[this.mes.length - 1].dom.style.display = "";
    this.mes[this.mes.length - 1].dom.style.backgroundPosition = ArtWord.BG_TABLE["%"];
};

ArtWord.prototype.set = function (val) {
    var str = val.toFixed(0);
    var meInd = this.mes.length - 2;
    for (var i = str.length - 1; i >= 0; i--) {
        this.mes[meInd].dom.style.display = "";
        this.mes[meInd].dom.style.backgroundPosition = ArtWord.BG_TABLE[str[i]];
        meInd--;
    }
    var realDigit = meInd + 1;

    while (meInd >= 0) {
        this.mes[meInd].dom.style.display = "none";
        meInd--;
    }

    this.refresh(realDigit);
};

ArtWord.prototype.refresh = function (realDigit) {
    // var w = realDigit * this.cellW;
    var w = this.digit * this.cellW;
    var w2 = w / 2;
    var pos = 0;
    for (var i = realDigit; i < this.mes.length; i++) {
        var me = this.mes[i];
        me.x = -w2 + (pos * this.cellW) + this.cellW / 2;
        pos++;
    }
};


var TWidget = function () {
    this.mes = [];
};

TWidget.prototype.addMe = function (me) {
    this.mes.push(me);
    return me;
};
TWidget.prototype.removeMe = function (me) {
    for (var i = 0; i < this.mes.length; i++) {
        if (me == this.mes[i]) {
            return this.mes.splice(i, 1)[0];
        }
    }
    return null;
};

TWidget.prototype.update = function (dt) {
    var size = {
        width: window.innerWidth,
        height: window.innerHeight
    };
    var origin = {
        x: size.width / 2,
        y: size.height / 2
    };
    var ph = size.width / 750;
    for (var i = 0; i < this.mes.length; i++) {
        this.mes[i].update(ph, origin, size);
    }
};

var LoadingDom = {
    loadPerV: 0,
    bgDom: null,
    init: function () {
        this.onInit();
        this._updateId = setInterval(this.update.bind(this), 16);
    },
    createAbsoluteDom: function (domName, style) {
        style = style || {};
        Object.assign(style, {
            position: "absolute",
        });
        var dom = document.createElement(domName);
        Object.assign(dom.style, style);
        return dom;
    },
    addPic: function (src, x, y, width, height) {
        var img = new Image();
        img.src = src;
        Object.assign(img.style, {
            position: "absolute",
            pointerEvents: "none",
        });
        this.splash.appendChild(img);
        return this.twidget.addMe(new CMelement(img, x, y, width, height));
    },
    parseUrlParam: function () {
        var url = window.location.href;
        var parse = url.substring(url.indexOf("?") + 1);
        var params = parse.split("&");
        var len = params.length;
        var item = [];
        var param = {};
        for (var i = 0; i < len; i++) {
            item = params[i].split("=");
            param[item[0]] = item[1];
        }

        return param;
    },
    update() {
        this.twidget.update();
        this.onUpdate();
    },
    finish() {
        if (!this.__syncLoadingOk) {
            return;
        }
        this.update();
        clearInterval(this._updateId);
        this.onFinish();
    },
    
    onInit: function(){
        this.twidget = new TWidget();
        this.splash = document.getElementById("splash");
        this.loadWord = document.getElementById("loadWord");
        this.loadWordValue = this.loadWord.children[0];

        Object.assign(this.loadWord.style, {
            position: "absolute",
            color: "#000",
        });

        this.twidget.addMe(new CMelement(this.loadWord, 0, 30, 750));
        this.twidget.addMe(new FontMelement(this.loadWord, 25));
    },
    onUpdate: function(){
        this.loadWordValue.innerText = this.loadPerV.toFixed(0);
    },
    onFinish: function(){
        var fadeOutSplash = function () {
            var opacity = 1;
            var intervalId = setInterval(function () {
                opacity -= 0.08;
                splash.style.opacity = opacity.toFixed(2);
                if (opacity <= 0) {
                    clearInterval(intervalId);
                    splash.style.display = 'none';
                    window.utils.msgHub.emit(window.utils.macro.EVENTS.SPLASH_OUT);
                }
            }, 50);
        };
        utils.loader.once("load-end", fadeOutSplash, this);
    },
};
LoadingDom.init();

window.boot = function () {
    var settings = window._CCSettings;
    window._CCSettings = undefined;
    var onProgress = null;

    var RESOURCES = cc.AssetManager.BuiltinBundleName.RESOURCES;
    var INTERNAL = cc.AssetManager.BuiltinBundleName.INTERNAL;
    var MAIN = cc.AssetManager.BuiltinBundleName.MAIN;
    function setLoadingDisplay() {
        // Loading splash scene
        var splash = document.getElementById('splash');
        onProgress = function (finish, total) {
            var percent = 100 * finish / total;
            LoadingDom.loadPerV = percent;
        };
        splash.style.display = 'block';
        cc.director.once(cc.Director.EVENT_AFTER_SCENE_LAUNCH, function () {
            LoadingDom.finish();
        });
    }

    var onStart = function () {

        cc.view.enableRetina(true);
        cc.view.resizeWithBrowserSize(true);

        if (cc.sys.isBrowser) {
            setLoadingDisplay();
        }

        if (cc.sys.isMobile) {
            if (settings.orientation === 'landscape') {
                cc.view.setOrientation(cc.macro.ORIENTATION_LANDSCAPE);
            }
            else if (settings.orientation === 'portrait') {
                cc.view.setOrientation(cc.macro.ORIENTATION_PORTRAIT);
            }
            cc.view.enableAutoFullScreen([
                cc.sys.BROWSER_TYPE_BAIDU,
                cc.sys.BROWSER_TYPE_BAIDU_APP,
                cc.sys.BROWSER_TYPE_WECHAT,
                cc.sys.BROWSER_TYPE_MOBILE_QQ,
                cc.sys.BROWSER_TYPE_MIUI,
                cc.sys.BROWSER_TYPE_HUAWEI,
                cc.sys.BROWSER_TYPE_UC,
            ].indexOf(cc.sys.browserType) < 0);
        }

        // Limit downloading max concurrent task to 2,
        // more tasks simultaneously may cause performance draw back on some android system / browsers.
        // You can adjust the number based on your own test result, you have to set it before any loading process to take effect.
        if (cc.sys.isBrowser && cc.sys.os === cc.sys.OS_ANDROID) {
            cc.assetManager.downloader.maxConcurrency = 2;
            cc.assetManager.downloader.maxRequestsPerFrame = 2;
        }

        var launchScene = settings.launchScene;
        var bundle = cc.assetManager.bundles.find(function (b) {
            return b.getSceneInfo(launchScene);
        });

        bundle.loadScene(launchScene, null, onProgress,
            function (err, scene) {
                if (!err) {
                    cc.director.runSceneImmediate(scene);
                    if (cc.sys.isBrowser) {
                        // show canvas
                        var canvas = document.getElementById('GameCanvas');
                        canvas.style.visibility = '';
                        var div = document.getElementById('GameDiv');
                        if (div) {
                            div.style.backgroundImage = '';
                        }
                        // console.log('Success to load scene: ' + launchScene);
                    }
                }
            }
        );

    };
    //canvas透明。
    // cc.macro.ENABLE_TRANSPARENT_CANVAS = true;

    var option = {
        id: 'GameCanvas',
        debugMode: settings.debug ? cc.debug.DebugMode.INFO : cc.debug.DebugMode.ERROR,
        showFPS: settings.debug,
        frameRate: 60,
        groupList: settings.groupList,
        collisionMatrix: settings.collisionMatrix,
    };

    cc.assetManager.init({
        bundleVers: settings.bundleVers,
        remoteBundles: settings.remoteBundles,
        server: settings.server
    });

    var bundleRoot = [INTERNAL];
    settings.hasResourcesBundle && bundleRoot.push(RESOURCES);

    var count = 0;
    function cb(err) {
        if (err) return console.error(err.message, err.stack);
        count++;
        if (count === bundleRoot.length + 1) {
            cc.assetManager.loadBundle(MAIN, function (err) {
                if (!err) cc.game.run(option, onStart);
            });
        }
    }

    cc.assetManager.loadScript(settings.jsList.map(function (x) { return 'src/' + x; }), cb);

    for (var i = 0; i < bundleRoot.length; i++) {
        cc.assetManager.loadBundle(bundleRoot[i], cb);
    }
};

if (window.jsb) {
    var isRuntime = (typeof loadRuntime === 'function');
    if (isRuntime) {
        require('src/settings.js');
        require('src/cocos2d-runtime.js');
        if (CC_PHYSICS_BUILTIN || CC_PHYSICS_CANNON) {
            require('src/physics.js');
        }
        require('jsb-adapter/engine/index.js');
    }
    else {
        require('src/settings.js');
        require('src/cocos2d-jsb.js');
        if (CC_PHYSICS_BUILTIN || CC_PHYSICS_CANNON) {
            require('src/physics.js');
        }
        require('jsb-adapter/jsb-engine.js');
    }

    cc.macro.CLEANUP_IMAGE_CACHE = true;
    window.boot();
}